home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / boot / czesc_2 / onekeyii / src / onekey.c < prev    next >
C/C++ Source or Header  |  1992-11-23  |  7KB  |  306 lines

  1. /*
  2.  * OneKeyII
  3.  * 
  4.  * Inspired by OneKey, a program by Carolyn Scheppner of CATS.
  5.  * This incarnation fixes some problems OneKey had with 2.1,
  6.  * adds a few useful features and improves compatibility with
  7.  * other programs.
  8.  *
  9.  * Code was rather cobbled together with stuff I had lying at
  10.  * hand, so please excuse any lack of clarity.
  11.  *
  12.  * #include <std_disclaimer.h>    // no warranties attached.
  13.  * Placed in the public domain by
  14.  * Martin W. Scott, Monday 23-Nov-92.
  15.  */
  16. #include <exec/libraries.h>
  17. #include <libraries/commodities.h>
  18. #include <dos/dos.h>
  19. #include <clib/exec_protos.h>
  20. #include <clib/alib_protos.h>
  21. #include <clib/alib_stdio_protos.h>
  22. #include <clib/commodities_protos.h>
  23. #include <devices/inputevent.h>
  24.  
  25. #include "icon.h"    /* my icon routines */
  26.  
  27. #define INTERRUPT void __interrupt __saveds
  28.  
  29. BOOL OpenLibs(void);
  30. void CloseLibs(void);
  31. void _main(void);
  32. void ProcessMsg(void);
  33. INTERRUPT OneKeyHandler(CxMsg *, CxObj *);
  34.  
  35. extern void DrawState(UWORD);
  36. extern void InitWindowPos(void);
  37. extern BOOL ShowWindow(void);
  38. extern void HideWindow(void);
  39. extern BOOL HandleIDCMP(void);
  40.  
  41. extern struct WBStartup *WBenchMsg;
  42. struct Library *CxBase, *IconBase, *GadToolsBase;
  43. struct GfxBase *GfxBase;
  44. struct IntuitionBase *IntuitionBase;
  45. struct MsgPort *broker_mp;
  46. CxObj *broker, *cocustom, *popobj;
  47.  
  48. struct NewBroker newbroker =
  49. {
  50.     NB_VERSION,
  51.     "OneKeyII",            /* string to identify this broker */
  52.     "OneKeyII",
  53.     "Type one-key-at-a-time (public domain)",
  54.     NBU_UNIQUE | NBU_NOTIFY,
  55.     COF_SHOW_HIDE
  56. };
  57.  
  58. UBYTE *vers = "\0$VER: OneKeyII 1.0";
  59.  
  60. struct Task *task;
  61. ULONG cxsigflag, signal, cxobjsignal;
  62. UWORD quals;
  63. BOOL toggle;
  64.  
  65.  
  66. #define EVT_POPKEY 1L
  67.  
  68. BOOL
  69. OpenLibs()            /* open required libraries */
  70. {
  71.     if ((GfxBase = (void *) OpenLibrary("graphics.library", 0L)) &&
  72.     (IntuitionBase = (void *) OpenLibrary("intuition.library", 37L)) &&
  73.     (GadToolsBase = (void *) OpenLibrary("gadtools.library", 37L)) &&
  74.     (IconBase = (void *) OpenLibrary("icon.library", 37L)) &&
  75.     (CxBase = (void *) OpenLibrary("commodities.library", 37L)))
  76.     return TRUE;
  77.     CloseLibs();
  78.     return FALSE;
  79. }
  80.  
  81. void
  82. CloseLibs()            /* close opened libraries */
  83. {
  84.     if (IconBase)
  85.     CloseLibrary(IconBase);
  86.     if (CxBase)
  87.     CloseLibrary(CxBase);
  88.     if (GfxBase)
  89.     CloseLibrary(GfxBase);
  90.     if (IntuitionBase)
  91.     CloseLibrary(IntuitionBase);
  92.     if (GadToolsBase)
  93.     CloseLibrary(GadToolsBase);
  94. }
  95.  
  96. void
  97. _main()
  98. {
  99.     UBYTE *popstr;
  100.     CxMsg *msg;
  101.  
  102.     if (OpenLibs())
  103.     {
  104.     if (broker_mp = CreateMsgPort())
  105.     {
  106.         newbroker.nb_Port = broker_mp;
  107.         cxsigflag = 1L << broker_mp->mp_SigBit;
  108.  
  109.         GetOurIcon(WBenchMsg);
  110.         newbroker.nb_Pri = (BYTE) TTInt("CX_PRIORITY", 127);
  111.         popstr = TTString("CX_POPKEY", "control 1");
  112.  
  113.         if (broker = CxBroker(&newbroker, NULL))
  114.         {
  115.  
  116.         if (cocustom = CxCustom(OneKeyHandler, 0L))
  117.         {
  118.             AttachCxObj(broker, cocustom);
  119.  
  120.             /* Allocate a signal bit for the signal CxObj */
  121.             if ((signal = (ULONG) AllocSignal(-1L)) != -1)
  122.             {
  123.             /* set up the signal mask */
  124.             cxobjsignal = 1L << signal;
  125.             cxsigflag |= cxobjsignal;
  126.             task = FindTask(NULL);
  127.  
  128.             /* NB: hotkey added AFTER handler, so it works with one-key */
  129.             if (popobj = HotKey(popstr, broker_mp, EVT_POPKEY))
  130.             {
  131.                 AttachCxObj(broker, popobj);
  132.  
  133.                 toggle = TTBool("TOGGLE", FALSE);
  134.                 InitWindowPos();
  135.                 if (TTBool("CX_POPUP", TRUE))
  136.                 ShowWindow();
  137.                 FreeOurIcon();
  138.  
  139.                 ActivateCxObj(broker, 1L);
  140.                 ProcessMsg();
  141.                 HideWindow();
  142.  
  143.                 FreeSignal(signal);
  144.             }
  145.  
  146.             }
  147.         }
  148.         DeleteCxObjAll(broker);
  149.  
  150.         /* Empty the port of all CxMsgs */
  151.         while (msg = (CxMsg *) GetMsg(broker_mp))
  152.             ReplyMsg((struct Message *) msg);
  153.  
  154.         }
  155.         DeleteMsgPort(broker_mp);
  156.     }
  157.     CloseLibs();
  158.     }
  159. }
  160.  
  161. void
  162. ProcessMsg(void)
  163. {
  164.     extern struct MsgPort *broker_mp;
  165.     extern CxObj *broker;
  166.     extern ULONG cxsigflag, winsigflag;
  167.     extern struct Window *window;
  168.     CxMsg *msg;
  169.     ULONG sigrcvd, msgid, msgtype;
  170.     LONG returnvalue = 1L;
  171.  
  172.     while (returnvalue)
  173.     {
  174.     sigrcvd = Wait(SIGBREAKF_CTRL_C | cxsigflag | winsigflag);
  175.  
  176.     while (msg = (CxMsg *) GetMsg(broker_mp))
  177.     {
  178.         msgid = CxMsgID(msg);
  179.         msgtype = CxMsgType(msg);
  180.         ReplyMsg((struct Message *) msg);
  181.  
  182.         switch (msgtype)
  183.         {
  184.         case CXM_IEVENT:
  185.         if (msgid == EVT_POPKEY)
  186.             if (window)
  187.             WindowToFront(window);
  188.             else
  189.             ShowWindow();
  190.         break;
  191.         case CXM_COMMAND:
  192.         switch (msgid)
  193.         {
  194.         case CXCMD_UNIQUE:
  195.         case CXCMD_APPEAR:
  196.             ShowWindow();
  197.             break;
  198.         case CXCMD_DISAPPEAR:
  199.             HideWindow();
  200.             break;
  201.         case CXCMD_DISABLE:
  202.             ActivateCxObj(broker, 0L);
  203.             break;
  204.         case CXCMD_ENABLE:
  205.             ActivateCxObj(broker, 1L);
  206.             break;
  207.         case CXCMD_KILL:
  208.             returnvalue = 0L;
  209.             break;
  210.         }
  211.         }
  212.     }
  213.  
  214.     if (sigrcvd & SIGBREAKF_CTRL_C)
  215.         returnvalue = 0L;
  216.  
  217.     if (sigrcvd & winsigflag)
  218.         if (!HandleIDCMP())
  219.         returnvalue = 0L;
  220.  
  221.     /* Check to see if the signal CxObj signalled us. */
  222.     if ((sigrcvd & cxobjsignal) && window)
  223.         DrawState(quals);
  224.     }
  225. }
  226.  
  227. /******************************************************************************/
  228. /*                                          */
  229. /*    ONEKEY HANDLER                                  */
  230. /*                                          */
  231. /******************************************************************************/
  232.  
  233. #define KCNT    7
  234. #define CODE_LSHIFT    0x60
  235. #define CODE_RSHIFT    0x61
  236. #define CODE_CONTROL    0x63
  237. #define CODE_LALT    0x64
  238. #define CODE_RALT    0x65
  239. #define CODE_LAMIGA    0x66
  240. #define CODE_RAMIGA    0x67
  241.  
  242. UWORD kcodes[] =
  243. {
  244.     CODE_LSHIFT, CODE_RSHIFT,
  245.     CODE_LALT, CODE_RALT,
  246.     CODE_LAMIGA, CODE_RAMIGA,
  247.     CODE_CONTROL
  248. };
  249.  
  250. UWORD kquals[] =
  251. {
  252.     IEQUALIFIER_LSHIFT, IEQUALIFIER_RSHIFT,
  253.     IEQUALIFIER_LALT, IEQUALIFIER_RALT,
  254.     IEQUALIFIER_LCOMMAND, IEQUALIFIER_RCOMMAND,
  255.     IEQUALIFIER_CONTROL
  256. };
  257.  
  258. #define ALL_BUTTONS     (IEQUALIFIER_LEFTBUTTON|IEQUALIFIER_RBUTTON|IEQUALIFIER_MIDBUTTON)
  259. #define KEY_QUAL    (IEQUALIFIER_LSHIFT|IEQUALIFIER_RSHIFT \
  260.             |IEQUALIFIER_CONTROL \
  261.             |IEQUALIFIER_LALT|IEQUALIFIER_RALT \
  262.             |IEQUALIFIER_LCOMMAND|IEQUALIFIER_RCOMMAND)
  263.  
  264. INTERRUPT
  265. OneKeyHandler(register CxMsg * cxm, CxObj * co)
  266. {
  267.     extern struct Window *window;    /* display window */
  268.     struct InputEvent *ie;
  269.     UWORD oldquals, i;
  270.     BOOL wasqual;        /* is this a qualifier? */
  271.  
  272.     ie = (struct InputEvent *) CxMsgData(cxm);
  273.     oldquals = quals;    /* spot the difference below... */
  274.  
  275.     if (ie->ie_Class == IECLASS_RAWKEY)
  276.     {
  277.     if (!(ie->ie_Code & IECODE_UP_PREFIX))    /* a downstroke */
  278.     {
  279.         /* is code a qualifier key? */
  280.         for (i = 0, wasqual = FALSE; i < KCNT; i++)
  281.         if (ie->ie_Code == kcodes[i])
  282.         {
  283.             if (toggle)
  284.             quals ^= kquals[i];
  285.             else
  286.             quals |= kquals[i];
  287.             wasqual = TRUE;
  288.         }
  289.  
  290.         if (!wasqual && quals)    /* non-qualifier - add quals */
  291.         {
  292.         ie->ie_Qualifier |= quals;    /* coallesce qualifiers */
  293.         quals = 0;            /* reset them */
  294.         }
  295.     }
  296.     }
  297.     else if (ie->ie_Class == IECLASS_RAWMOUSE)  /* mouse-cancel? */
  298.     {
  299.     if (ie->ie_Code != IECODE_NOBUTTON && (ie->ie_Qualifier & KEY_QUAL))
  300.         quals = 0;
  301.     }
  302.  
  303.     if (oldquals != quals && window)    /* update display */
  304.     Signal(task, cxobjsignal);
  305. }
  306.